package info.xmlprint.ui.widgets;

import info.xmlprint.core.mapping.ElementPathNode;
import info.xmlprint.core.project.PrintProject;
import info.xmlprint.core.xml.PAttribut;
import info.xmlprint.core.xml.PElement;
import info.xmlprint.ui.message.GuiMessages;

import java.util.List;

import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;

public class ElementAttributTreeViewer extends TreeViewer implements
		IObserverControl, ISetupComposite {
	private PrintProject printProject;

	public ElementAttributTreeViewer(Composite parent, int style) {
		super(parent, style | SWT.CHECK);
		init();
	}

	private void init() {
		final Tree tree = getTree();
		tree.setHeaderVisible(true);
		final TreeColumn treeColumn = new TreeColumn(tree, SWT.LEFT);
		treeColumn.setText("Attribute:");
		treeColumn.setWidth(200);

		setContentProvider(new ITreeContentProvider() {

			public void dispose() {
			}

			public Object[] getChildren(Object in) {
				if (in instanceof PAttribut) {
					PAttribut pa = (PAttribut) in;
					List<String> list = pa.getList();
					if (list != null && list.size() > 0)
						return list.toArray();
				}
				return null;
			}

			public Object[] getElements(Object in) {
				if (in instanceof ElementPathNode) {
					ElementPathNode node = (ElementPathNode) in;
					//PElement pe = node.getPElement();
					  PElement pe =printProject.getPElementGroup().getElement(node.getPElement().getName());
					PAttribut[] pa = pe.getAttributs();

					String s = "";
					for (PAttribut p : pa) {
						s += p.getName();
					}

					if (s.equals(""))
						return new Object[0];

					return pa;
				}

				return null;
			}

			public Object getParent(Object element) {
				return null;
			}

			public boolean hasChildren(Object in) {
				if (in instanceof PAttribut) {
					PAttribut pa = (PAttribut) in;
					if (pa.getName().equals(""))
						return false;

					List<String> list = pa.getList();
					if (list != null && list.size() > 0)
						return true;
				}
				return false;
			}

			public void inputChanged(Viewer viewer, Object oldInput,
					Object newInput) {
			}
		});

		setLabelProvider(new ITableLabelProvider() {
			public void addListener(ILabelProviderListener listener) {
			}

			public void dispose() {
			}

			public Image getColumnImage(Object element, int columnIndex) {
				return null;
			}

			public String getColumnText(Object in, int columnIndex) {
				if (in instanceof PAttribut) {
					PAttribut pa = (PAttribut) in;
					if (pa.getName().equals(""))
						return "["
								+ GuiMessages.Stileditor_Gui_WithoutAttribute
								+ "]";

					return pa.getName();

				} else if (in instanceof String) {
					String s = (String) in;
					if (!s.equals(""))
						return "= \"" + s + "\"";
				}

				return null;
			}

			public boolean isLabelProperty(Object element, String property) {
				return false;
			}

			public void removeListener(ILabelProviderListener listener) {
			}
		});

		tree.addListener(SWT.Selection, new Listener() {

			@Override
			public void handleEvent(Event event) {
				if (event.detail == SWT.CHECK) {
					TreeItem currTi = (TreeItem) event.item;
					String currName = tiFilter(currTi.getText());
					ElementPathNode epn = (ElementPathNode) getInput();
					 
					// Attribut Node
					for (TreeItem t : currTi.getItems()) {
						if (currTi.getChecked()) {
							t.setChecked(true);
							epn.addAttribut(currName);
							epn.addAttrWithSelectAll(currName); 
							epn.addValue(currName, tiFilter(t.getText())); 
						} else {
							epn.removeAttribut(currName);
							epn.removeAttrWithSelectAll(currName); 
							t.setChecked(false);
						}
					}

					// Value Node
					if (currTi.getParentItem() != null) {
						TreeItem parentTi = currTi.getParentItem();
						String attrName = parentTi.getText();

						if (!currTi.getChecked()) {
							parentTi.setChecked(false);
							
							epn.removeAttrWithSelectAll(attrName); 
							for (TreeItem t : parentTi.getItems()) {
								if (!t.getChecked()) { 
									epn.removeValue(attrName,  tiFilter(t.getText()));
								}else{
									epn.addValue(attrName,  tiFilter(t.getText()));
								}
							}
						} else {
							epn.addAttribut(attrName);
							epn.addValue(attrName, currName);

							// Wenn alle Value Node gekreuzt, wird Attrubut Node
							// gekreuzt.
							boolean allChildrenChecked = true;
							for (TreeItem t : parentTi.getItems()) {
								if (!t.getChecked()) {
									// Wenn ein nicht
									// gekreuzt
									allChildrenChecked = false;
									break;
								}
							}
							if (allChildrenChecked) {
								parentTi.setChecked(true);
								epn.addAttrWithSelectAll(attrName);
							}else{
								epn.removeAttrWithSelectAll(attrName);
							}
						}	
					}
				}

			}
		});
	}

	private String tiFilter(String s) {
		s = s.replaceAll("^= \"", "");
		s = s.replaceAll("\"$", "");
		return s;
	}

	@Override
	public void updateControl() {
		refresh();
		expandAll();
		setTreeCheckBox();
	}

	@Override
	public void setPrintProject(PrintProject printProject) {
		this.printProject=printProject;
	}

	private void setTreeCheckBox() {
		Tree tree = getTree();
		String attrName, val;
		ElementPathNode epn = (ElementPathNode) getInput();
		boolean allChildrenChecked;
	
		for (TreeItem ti : tree.getItems()) {
			attrName = ti.getText();
			allChildrenChecked = true;
			 
			for (TreeItem ti2 : ti.getItems()) {
				val = tiFilter(ti2.getText());
				if (epn.hasValue(attrName, val) || epn.isSelectAll(attrName))
					ti2.setChecked(true);
				else
					allChildrenChecked = false;
			}
			if (allChildrenChecked)
				ti.setChecked(true);
		}
	}

}
